package pacs_server

import (
	"fmt"
	"gitee.com/uni-minds/bridge-pacs/dcm4chee"
	"gitee.com/uni-minds/bridge-pacs/tools"
	nested "github.com/antonfisher/nested-logrus-formatter"
	"github.com/sirupsen/logrus"
	"time"
)

type FeedInfo struct {
	Start int
	Step  int
}

func NewSyncWorker(pi *PacsServer, id int, enableLog bool, chanFree chan int) *SyncWorker {
	worker := &SyncWorker{
		Id:              id,
		pacsServer:      pi,
		chanFree:        chanFree,
		chanFeed:        make(chan FeedInfo, 1),
		chanStop:        make(chan int, 0),
		enableQuickMode: false,
	}
	worker.ClearStatus()
	if enableLog {
		logger := logrus.New()
		logger.SetFormatter(&nested.Formatter{
			FieldsOrder:     []string{"module", "msg"},
			TimestampFormat: "20060102T150405",
			HideKeys:        true,
			NoColors:        true,
		})
		logger.SetLevel(logrus.TraceLevel)
		worker.logger = logger.WithField("module", fmt.Sprintf("wk_%d", id))
	}
	return worker
}

func (worker *SyncWorker) UseQuickMode() {
	worker.enableQuickMode = true
}

func (worker *SyncWorker) IsBusy() bool {
	return worker.flagBusy
}

func (worker *SyncWorker) Feed(start, step int) {
	worker.chanFeed <- FeedInfo{
		Start: start,
		Step:  step,
	}
}

func (worker *SyncWorker) Start() {
	worker.chanFree <- worker.Id
	for {
		select {
		// 结束
		case <-worker.chanStop:
			worker.Logf("get stop signal")
			close(worker.chanFeed)
			close(worker.chanStop)
			return

		// 存在feed信息
		case feedInfo := <-worker.chanFeed:
			worker.flagBusy = true
			worker.Logf("start %d, step +%d", feedInfo.Start, feedInfo.Step)

			connector := dcm4chee.NewConnector(worker.pacsServer.ServerHost, worker.pacsServer.ServerAETs)

			jdata, err := connector.GetStudiesFromOffset(feedInfo.Start, feedInfo.Step)
			if err != nil {
				worker.Logf("finish with error: %s", err.Error())

			} else {
				for _, data := range jdata {
					var studiesId string
					if studiesId, err = dcm4chee.QueryDataString(data, dcm4chee.DICOM_STUDY_ID); err != nil {
						worker.Logf(err.Error())
					}

					if worker.enableQuickMode {
						_, err = worker.pacsServer.FindStudiesByIdLocal(studiesId)
						if err == nil {
							continue
						}
					}

					if url, err := dcm4chee.QueryDataString(data, dcm4chee.DICOM_RETRIEVE_URL); err != nil {
						worker.Logf(err.Error())
					} else if studiesInfo, err := StudiesAnalysis(connector, studiesId); err != nil {
						worker.Logf(err.Error())
					} else {
						sdate, _ := dcm4chee.QueryDataString(data, dcm4chee.DICOM_STUDY_DATE)
						stime, _ := dcm4chee.QueryDataString(data, dcm4chee.DICOM_STUDY_TIME)
						sDatetime, _ := tools.Dcm4cheDateTimeDecode(sdate, stime)

						studiesInfo.StudyDatetime = sDatetime.Format(time.RFC3339)
						studiesInfo.URL = url

						if details, err := worker.pacsServer.ImportStudies(studiesInfo); err != nil {
							worker.Logf(err.Error())
						} else {
							worker.Stat.CountSeries += details.CountSeries
							worker.Stat.CountStudies += details.CountStudies
							worker.Stat.CountInstance += details.CountInstance
							worker.Stat.ImportStudies = append(worker.Stat.ImportStudies, details.ImportStudies...)
						}
					}

				}
				worker.Logf("finish %d, step +%d", feedInfo.Start, feedInfo.Step)
			}
			worker.flagBusy = false
			worker.Logf("chan size: %d", len(worker.chanFree))
			worker.chanFree <- worker.Id
		}
	}
}

func (worker *SyncWorker) Stop() {
	worker.chanStop <- 1
}

func (worker *SyncWorker) ClearStatus() (status ImportDetails) {
	status = worker.Stat
	worker.Stat = ImportDetails{
		CountStudies:  0,
		CountSeries:   0,
		CountInstance: 0,
		ImportStudies: make([]string, 0),
	}
	return status
}

func (s *SyncWorker) Logf(format string, msg ...interface{}) {
	if s.logger != nil {
		s.logger.Printf(format, msg...)
	}
}
